(define factorial (lambda (x) (if (= x 1) 1 (* x (factorial (- x 1))))))

(define quadraticEquation (lambda (a b c)
      (if (= (- (* b b) (* 4 a c) ) 0)
      (/ (- 0 b) (* 2 a) )
      (list
              (/ (- (- b) (sqrt (- (* b b) (* 4 a c)))) (* 2 a))
              (/ (+ (- b) (sqrt (- (* b b) (* 4 a c)))) (* 2 a))
      ))
))

(define fibonacciR (lambda (n)
      (if (= n 1) 1 (if (= n 0) 0 (+ (fibonacciR(- n 1)) (fibonacciR(- n 2)) )
 ))
))

(define fibonacci (lambda (n)
      (fibonacciR n)
))

(define GCD
 (lambda (a b)
  (if (> a b)
      (if (= 0 b) a (GCD (remainder a b) b))
      (if (= 0 a) b (GCD (remainder b a) a))
      ))
)
(define power
 (lambda (num exp)
  (let ((next
         (if (< exp 2) 1 (power (* num num) (quotient exp 2)))
         ))
    (if (= 1 (remainder exp 2))
        (* num next)
        next
        )
    ))
 )

(define quadraticEquation2
    (lambda (a b c)
        (let ((sdelta (sqrt (- (* b b) (* 4 a c)))))
            (if (= sdelta 0)
                (list (/ (- b) (* 2 a)) )
                (list (/ (- (- b) sdelta) (* 2 a)) (/ (+ (- b) sdelta) (* 2 a)) )
            )
        )
    )
)

(define factorialI (lambda (n)
      (do ((i n (- i 1))
           (s 1 s))
        ((= i 0) s)
        (set! s (* s i)))))


;HW3

(define dlugosc
    (lambda (lista)
        (if (null? lista)
            0
            (+ 1 (dlugosc(cdr lista)))
        )
    )
)

(define k-ty
    (lambda (lista k)
        (if (= k 0)
            (car lista)
            (k-ty (cdr lista) (- k 1))
        )
    )
)

(define zostawK
    (lambda (lista k)
        (if (or (null? lista) (<= k 0))
            '()
            (cons (car lista) (zostawK (cdr lista) (- k 1)))
        )
    )
)

(define utnijK 
    (lambda (lista k)
        (if (null? lista)
            '()
            (if (< k 0)
                (append (list (car lista)) (utnijK (cdr lista) (- k 1)))
                (utnijK (cdr lista) (- k 1))
            )
        )
    )
)

(define coDrugi
    (lambda (lista)
        (if (or (null? lista) (null? (cdr lista)))
            '()
            (cons (cadr lista) (coDrugi (cddr lista)))
        )
    )
)

(define naLiscie
    (lambda (lista k)
        (if (null? lista)
            #f
            (if (= (car lista) k)
                #t
                (naLiscie (cdr lista) k)
            )
        )
    )
)

(define mapuj
    (lambda (lista fcja)
        (if (null? lista)
            '()
            (cons (fcja (car lista)) (mapuj (cdr lista) fcja))
        )
    )
)

(define filtruj
    (lambda (lista fcja)
        (if (null? lista)
            '()
            (if (fcja (car lista))
                (cons (car lista) (filtruj (cdr lista) fcja))   
                (filtruj (cdr lista) fcja)
            )
        )
    )
)

(define odwroc
    (lambda (lista)
        (if (null? lista)
            '()
            (append (odwroc (cdr lista)) (list (car lista)))
        )  
    )
)

(define polacz
    (lambda (lista1 lista2)
        (if (null? lista1)
            (if (null? lista2)
                '()
                (cons (car lista2) (polacz '() (cdr lista2)))
            )
            (cons (car lista1) (polacz (cdr lista1) lista2))
         )
    )
)

(define przeplatanie
    (lambda (lista1 lista2)
        (if (null? lista1)
            (if (null? lista2)
                '()
                (przeplatanie lista2 lista1)
            )
            (cons (car lista1) (przeplatanie lista2 (cdr lista1)))       
        )
    )
)

(define listaPar
    (lambda (lista1 lista2)
        (if (null? lista1)
            (if (null? lista2)
                '()
                (cons (cons '() (car lista2)) (listaPar '() (cdr lista2)))
            )
            (cons (cons (car lista1) (car lista2)) (listaPar (cdr lista1) (cdr lista2)))
        )
    )
)

(begin
      (display (factorialI 5))
      (display #\newline)
      (display (quadraticEquation2 1 2 1))
      (display #\newline)
      (display (quadraticEquation2 1 1 1))
      (display #\newline)
      (display (fibonacci 11))
      (display #\newline)
      (display (GCD 20 125))
      (display #\newline)
      (display (power 20 10))
      (display #\newline)
      (display (dlugosc '(a b c (d e))))
      (display #\newline)
      (display (k-ty '(3 1 8 12 5 78 45 3 0 9) 2))
      (display #\newline)
      (display (naLiscie '(3 1 8 12 5 78 45 3 0 9) 2))
      (display #\newline)
      (display (naLiscie '(3 1 8 12 5 78 45 3 0 9) 8))
      (display #\newline)
      (display (mapuj '(3 1 8 12 5 78 45 3 0 9) -))
      (display #\newline)
      (display (odwroc '(3 1 8 12 5 78 45 3 0 9)))
      (display #\newline)
      (display (zostawK '(3 1 8 12 5 78 45 3 0 9) 2))
      (display #\newline)
      (display (utnijK '(3 1 8 12 5 78 45 3 0 9) 2))
      (display #\newline)
      (display (polacz '(3 1 8 12) '(5 78 45 3 0 9)))
      (display #\newline)
      (display (coDrugi '(3 1 8 12 5 78 45 3 0)))
      (display #\newline)
      (define wieksz2(lambda (a)(if (> a 2) #t #f)) )
      (display (filtruj '(3 1 8 12 5 78 45 3 0 9) wieksz2))
      (display #\newline)      
      (display (przeplatanie '(0 2 4 6 8 10) '(1 3 5 7 9 11 13 15)))
      (display #\newline)    
      (display (listaPar '(0 2 4 6 8 10) '(1 3 5 7 9 11 13 15)))
      (display #\newline)  
)